home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 21
/
Cream of the Crop 21 (Terry Blount) (October 1996).iso
/
program
/
oxcc1434.zip
/
SRC
/
CFAR.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-11-15
|
46KB
|
1,882 lines
/* cfar.c */
/* Import .o and .a (a.out format) files into a cff archive */
/* Version 2 now incorporates FILE mode, absorbing 'cfin' and 'cfdel' */
/* Copyright 1993, 1995 Norman D. Culver, All Rights Reserved */
/* compile: gcc -o -O2 -DSKELETON cfar.c */
typedef unsigned long size_t;
#include "oxbow.h"
extern void (*BUGPRINTF)(char *fmt, ...);
extern long atol(const char *);
extern int strlen(const char *);
extern void *strcpy(char *, const char *);
extern int _strcpy(char *, char *);
extern void memclr(char *, long);
extern int strlwr(char *);
extern void *strrchr(const char *, char);
extern void *strstr(const char *, const char *);
static void setup_origin(unsigned long, int);
extern void oxlink_close_libs(void);
/* Program version */
static Item prgversion = (Item)2;
/* Archive version */
static Item arversion;
/* Maximum library types */
#define MAXLIBTYPE 16
typedef struct {
unsigned long sn;
unsigned long libnum : 12; /* capacity for 4096 libraries per libtype */
unsigned long libtype : 4; /* capacity for 16 library types */
unsigned long unused : 12;
unsigned long tag : 4;
} SymItem;
typedef struct {
unsigned long filetime;
unsigned long sn : 28;
unsigned long tag : 4;
} OrgItem;
/* Action bitmap */
static int act;
#define arADD (1)
#define arREPLACE (2)
#define arDELETE (4)
#define arEXTRACT (8)
#define arCHECK (16)
#define arUPDATE (32)
static int verbose; /* if 1, verbose mode */
static long libtype; /* 0 = modules, 1 = classes */
static long oldlibtype = -1;
static long libnum; /* library number into which files are stored */
static long oldlibnum = -1;
static int map; /* if 1, print archive map */
static int map_bitmaps; /* if 1, and map, print bitmaps */
static int map_entries; /* if 1, and map, print entries */
static int freshen; /* if 1, freshen entries */
static int shrink; /* if 1, shrink archive */
static int issymbol; /* if 1, file names are really symbol names */
static int batfile; /* if 1, print a batchfile to remake archive */
static void *archive; /* handle of the open archive */
static void *msyms; /* handle of the master symbol table */
static void *fipaths; /* handle of the internal filemode path table */
static void *ipaths; /* handle of the internal path table */
static void *qipaths;
static void *origins; /* handle of the origin path table */
static void *qorigins;
static void *lib; /* handle of the current internal library */
static void *plib; /* handle of the library parent directory */
static char curlib[1024]; /* internal path to the current library */
static int curliblen;
static char curobj[1024]; /* internal path to the current file */
static int curobjlen;
static char *cur_orgpath; /* current origin path as given by cfpathtrn */
static int cur_orgtype; /* current origin type as given by cfpathtrn */
static OrgItem cur_org; /* current origin time and serial num */
static char ltypes[MAXLIBTYPE];
static char lnums[4096];
static int delete;
static int replace;
static int add;
static unsigned long
new_sn(char *name)
{
Item sn;
int namlen = strlen(name);
if(cffind(archive, name, namlen, &sn) >= FOUND)
{
++sn.a0;
cfreinsert(archive, name, namlen, &sn);
return sn.a0;
}
return 0;
}
/* ++++++++++++++++++++++++++++ DLLMODE ++++++++++++++++++++++++++++++++ */
static int dllmode;
static void
proc_dllmode(char *dllpath)
{
char buf[256];
char symbol[256];
char dllname[256];
char dlldef[256];
int ordinal, argcnt, symlen, match, deflen;
int filesize, filesize1;
long dupnum;
SymItem symval, saveval;
char *filename;
cfFILE *df;
CFSTAT sbuf;
void *xx, *xx1, *yy;
int dlltype, dll_sn;
char *cp;
filename = strrchr(dllpath, '/');
if(filename)
++filename;
else filename = dllpath;
deflen = _strcpy(dlldef, filename);
if(strstr(dlldef, ".w32"))
dlltype = 1<<4;
else if(strstr(dlldef, ".os2"))
dlltype = 2<<4;
else if(strstr(dlldef, ".lnx"))
dlltype = 3<<4;
else if(strstr(dlldef, ".w16"))
dlltype = 4<<4;
else if(strstr(dlldef, ".os1"))
dlltype = 5<<4;
else
dlltype = 0;
strcpy(curlib, "ltype3");
plib = cfsubopen(archive, curlib, F_RDWR|F_CREAT, NULL);
xx = cfsubopen(plib, dlldef, F_RDONLY, NULL);
if(!xx && delete)
{
cfprintf("cfar: %s does not exist\n", filename);
return;
}
if(xx && !(replace || delete))
{
cfclose(xx);
cfprintf("cfar: %s exists and replace not enabled\n", dlldef);
return;
}
if(add || replace)
{
if(!(xx1 = cfopen(dllpath, F_RDONLY, NULL)))
{
cfclose(xx);
cfprintf("cfar: cannot open %s\n", dllpath);
return;
}
cfstat(xx1, &sbuf);
setup_origin(sbuf.st_mtime, 1);
}
symbol[0] = '_'; /* add leading underscore to symbols */
if(xx && (replace || delete))
{/* DELETE ALL OF THE OLD SYMBOLS */
saveval.sn = 0;
/* get an in-memory uncompressed copy */
yy = cfsubopen(MEMTEMP, "", F_TEMPFILE, NULL);
filesize = cfunzip(yy,0,xx,0);
cfclose(xx);
/* convert the memory file to a stream FILE */
cfseek(yy, 0, S_SET);
df = cffdopen(yy, "rt");
while(cffgets(buf, sizeof(buf)-1, df))
{
if( buf[0] == '#' || !isalnum(buf[0]) )
continue;
if(buf[0] == 'U' && strstr(buf, "UNHANDLED "))
break;
if(isdigit(buf[0]))
{
if(!strstr(buf, "ERROR:"))
{
/* the symbol is stored as oooo sssssssss cccc\n */
cfsscanf(buf, "%d %s %d", &ordinal, &symbol[1], &argcnt);
/* Delete the symbol from msyms */
symlen = strlen(symbol);
dupnum = 0;
for(;;)
{
int result = cffind_dupnum(msyms, symbol, symlen, &symval, &dupnum);
if(result >= FOUND)
{
symval.unused = 0;
match = 0;
if(saveval.sn)
{
if(symval.sn == saveval.sn && symval.libtype == 3)
{
match = 1;
}
}
else
{/* first */
if(symval.libtype == 3)
{/* check if the dll names match */
int snum = symval.libnum;
symval.libnum = 0;
if(cfget(qipaths, &symval, 8, buf, 256) >= FOUND)
{
if(!strcmp(buf, dllname))
{
symval.libnum = snum;
saveval = symval;
match = 1;
}
}
}/* END: symval.libtype == 3 */
}/* END: first */
if(match)
{
if(cfdelete_dupnum(msyms, symbol, symlen, dupnum) != OK)
cfprintf("cfar: ERROR can't delete %s dumpnum=%d\n",
symbol, dupnum);
break;
}
++dupnum;
}/* END: result >= FOUND */
else break;
}/* END: for(;;) */
}/* END: !strstr(ERROR) */
}/* END: isdigit(buf[0]) */
else if((cp = strstr(buf, ".dll")))
{/* new dll encountered */
cp[4]=0;
if(saveval.sn)
{/* delete previous dll name from qipath */
int u = saveval.unused;
int n = saveval.libnum;
saveval.unused = 0;
saveval.libnum = 0;
cfdelete(qipaths, &saveval, 8);
saveval.unused = u;
saveval.libnum = n;
}
strcpy(dllname, buf);
saveval.sn = 0;
if(verbose)
cfprintf("delete %s\n", dllname);
continue;
}/* END: new dll encountered */
}/* END: while(cffgets()) */
/* delete last dllname from qipaths */
if(saveval.sn)
{
saveval.unused = 0;
saveval.libnum = 0;
cfdelete(qipaths, &saveval, 8);
}
cffclose(df); /* auto delete of tempfile yy */
/* Delete the internal copy of dlldef */
cfdelete(plib, dlldef, deflen);
/* Delete the origin linkage */
strcat(dlldef, ".org");
cfdelete(plib, dlldef, deflen+4);
dlldef[deflen] = 0;
}/* END: DELETE OLD SYMBOLS */
if(add || replace)
{/* INSERT NEW SYMBOLS */
/* get the compressed file size */
filesize = cfzip(0,0,xx1,0);
/* create a chunk to hold the compressed file */
xx = cfmake_chunk(plib, dlldef, deflen, filesize);
if(!xx)
{
cfprintf("cfar: cannot create internal file %s\n", filename);
cfclose(xx1);
return;
}
#if 1
/* compress the external file into the internal chunk */
cfseek(xx1, 0, S_SET);
if((filesize1 = cfzip(xx,0,xx1,0)) != fil